package delegation

import kotlin.reflect.KProperty

/**
 *@author LikeYouDo
 *@date 2024/12/13 16:16
 */
/**
 * Kotlin 提供了一种委托属性这允许将属性set和get方法的调用委托给某个对象。
 * 在这种情况下，委托对象应具有方法 getValue
 * 对于可变属性，委托对象还需要 setValue 方法
 */
class Example {
    var p: String by Delegate()

    override fun toString(): String {
        return "Example Class"
    }
}

class Delegate {
    operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${prop.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
        println("$value has been assigned to ${prop.name} in $thisRef")
    }
}

class LazySample {
    init {
        println("created!")
    }

    /**
     * 如果你想要线程安全，请改用 blockingLazy()：
     * 它保证仅在一个线程中计算值，
     * 并且所有线程都将看到相同的值。
     */
    val lazyStr: String by lazy {
        println("computed!")          // 2
        "my lazy"
    }

}


class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int by map
}

fun main() {
    val e = Example()
    println(e.p)
    e.p = "NEW"


    val sample = LazySample()
    println("lazyStr = ${sample.lazyStr}")  // 2
    println(" = ${sample.lazyStr}")  // 3

    //您也可以将可变属性委托给 map。在这种情况下，将在属性分配时修改映射。
    // 请注意，您将需要而不是 read-only 。MutableMapMap
    val user = User(
        mapOf(
            "name" to "Bob",
            "age" to 25
        )
    )

    println("name = ${user.name}, age = ${user.age}")
}